package me.huha.client;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;

import me.huha.commons.AddressDTO;
import me.huha.commons.ToCcBccAddressDTO;
import me.huha.commons.email.PropertiesDTO;
import me.huha.commons.email.UserEmailDTO;
import me.huha.listener.EmailTransportListener;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sun.mail.smtp.SMTPSendFailedException;

/**
 * @Title: EmailUtils.java
 * @Author: Yepx
 * @mail: yepx2013@gmail.com
 * @CreateTime: 2017年9月29日 上午10:59:36
 * @Todo: javax.mail 封装 
 */
public class EmailUtils extends EmailBase {
	
	private Logger logger = LoggerFactory.getLogger(EmailUtils.class);
	
	public EmailUtils(PropertiesDTO PropertiesDto, UserEmailDTO emailDto) {

		// TODO Auto-generated constructor stub
		super(PropertiesDto, emailDto);
	}
	
	@Override
	public Boolean sendEmail(String uuid, ToCcBccAddressDTO toCcBccAddress, String messageTitle, String messageContent, List<File> imgList,
			List<File> fileList, Map<String, String> extendMap) {

		Boolean result = false;
		
		try{
			// 传入参数smtp，transport将自动按照smtp协议发送邮件。
			transport = session.getTransport(super.propertiesDto.getSendEnum().getDesc());
			transport.addTransportListener(new EmailTransportListener());
			
			transport.connect(super.emailDto.getEmail(),super.emailDto.getPassWord());
			
			// Message对象用来储存实际发送的电子邮件信息
			MimeMessage message = new MimeMessage(session);
			message.setSubject(messageTitle);
			
			// 设定发件人信息
			message.setFrom(new InternetAddress(super.emailDto.getEmail(), super.emailDto.getNickName()));
			// 保存收件人，抄送人，密送人 
			message = this.saveToCcBccAddress(message, toCcBccAddress);
			
			// 设定邮件体
			Multipart multipart = this.setMultipart(messageContent, imgList, fileList);
			
			// Send the complete message parts
			message.setContent(multipart);
			message.saveChanges();
			message.setHeader("ONLY-ID", uuid);
			//TODO 设定特殊的标识在邮件头内
			if(!extendMap.isEmpty()){
				Set<String> keySet = extendMap.keySet();
				for (String key : keySet) {
					String value = extendMap.get(key);
					message.setHeader(key, value);
				}
				
			}
			transport.sendMessage(message, message.getAllRecipients());
			
			super.closeConnect();

			result = true;
		}catch(SMTPSendFailedException e) {
			logger.error("被拒收了");
			e.printStackTrace();
		}catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}
	
	
	/**
	 * 设定邮件体正文
	 * @param messageContent
	 * @param imgList
	 * @param fileList
	 * @return
	 * @throws MessagingException
	 * @throws UnsupportedEncodingException
	 */
    private Multipart setMultipart(String messageContent, List<File> imgList, List<File> fileList) throws MessagingException, UnsupportedEncodingException{
		
		// 创建一个multipar消息
        
		Multipart multipart = new MimeMultipart("related");
        //创建消息部分
        BodyPart messageBodyPart = new MimeBodyPart();

        // TODO 设定正文  后一个参数可以不指定编码，如"text/plain"，但是将不能显示中文字符
        if(imgList != null && imgList.size() > 0){
        	messageContent = messageContent + "<img src=\"cid:image\">";
        }
        messageBodyPart.setContent(messageContent, "text/html;charset=UTF-8");
        multipart.addBodyPart(messageBodyPart);
        
        int i = 0;
        //TODO 设定图片
        if(imgList != null && imgList.size() > 0){
        	
        	for (File img : imgList) {
        		 
        		 messageBodyPart = new MimeBodyPart();
                
        		 DataSource fds = new FileDataSource(img);

                 messageBodyPart.setDataHandler(new DataHandler(fds ,"application/octet-stream"));
                 messageBodyPart.setHeader("Content-ID", "<image>");
                 // add image to the multipart
                 multipart.addBodyPart(messageBodyPart, i);
                 i++;
			}
        }

        //TODO 设定附件
        if(fileList != null && fileList.size() > 0){
        	for (File file : fileList) {
        		
        		messageBodyPart = new MimeBodyPart();
        		 
                DataSource source = new FileDataSource(file);
                messageBodyPart.setDataHandler(new DataHandler(source));
                // 网上流传的解决文件名乱码的方法，其实用MimeUtility.encodeWord就可以很方便的搞定
                // 这里很重要，通过下面的Base64编码的转换可以保证你的中文附件标题名在发送时不会变成乱码
                messageBodyPart.setFileName(MimeUtility.encodeText(file.getName(), "UTF-8", "B"));
               
                multipart.addBodyPart(messageBodyPart, i);
                i++;
			}
        }
        
        return multipart;
	}
    
	/**
	 * 保存收件人，抄送人，密送人
	 * 
	 * @param message
	 * @param toCcBccAddress
	 * @return
	 * @throws UnsupportedEncodingException
	 * @throws MessagingException
	 */
	private MimeMessage saveToCcBccAddress(MimeMessage message, ToCcBccAddressDTO toCcBccAddress)
			throws UnsupportedEncodingException, MessagingException {

		/** 收件人 */
		List<AddressDTO> to = toCcBccAddress.getTo();
		/** 抄送人 */
		List<AddressDTO> cc = toCcBccAddress.getCc();
		/** 秘送人 */
		List<AddressDTO> bcc = toCcBccAddress.getBcc();

		if (to != null && !to.isEmpty() && to.size() > 0) {
			// 消息接收者设置(发件地址，昵称)，收件人看到的昵称是这里设定的
			InternetAddress[] internetAddressArr = new InternetAddress[to
					.size()];
			for (int i = 0; i < to.size(); i++) {
				internetAddressArr[i] = new InternetAddress(to.get(i).getEmail(), to.get(i).getNickName());
			}
			message.addRecipients(Message.RecipientType.TO, internetAddressArr);
			
		} 
		if (cc != null && !cc.isEmpty() && cc.size() > 0) {

			// 消息接收者设置(发件地址，昵称)，收件人看到的昵称是这里设定的
			InternetAddress[] internetAddressArr = new InternetAddress[cc.size()];
			for (int i = 0; i < cc.size(); i++) {
				internetAddressArr[i] = new InternetAddress(cc.get(i).getEmail(), cc.get(i).getNickName());
			}
			message.addRecipients(Message.RecipientType.CC, internetAddressArr);
		} 
		if (bcc != null && !bcc.isEmpty() && bcc.size() > 0) {

			// 消息接收者设置(发件地址，昵称)，收件人看到的昵称是这里设定的
			InternetAddress[] internetAddressArr = new InternetAddress[bcc.size()];
			for (int i = 0; i < bcc.size(); i++) {
				internetAddressArr[i] = new InternetAddress(bcc.get(i).getEmail(), bcc.get(i).getNickName());
			}
			message.addRecipients(Message.RecipientType.BCC, internetAddressArr);
		}
		message.saveChanges();
		return message;
	}
}
